# coding:utf8
'''
    用户相关
    # 状态 0表示假 1表示真
'''
from flask_restful import Resource, request
from _sys.function import md5Encode, send_email_by_model, inquiry_vip, allow_cross
from _sys.parser import parsers
from _sys.models import Token, ResponseJson, MongodbOperations,CreateId, HiddenSensitiveInfo, FormatIO
from _sys.code import dbNameDict

import time
import jwt


token = Token()
responseJson = ResponseJson()
mgOp = MongodbOperations()
dbName = dbNameDict
ctId = CreateId()
hidSI = HiddenSensitiveInfo()

class User(Resource):
    '''
        /user/u
        get --用户获取用户信息
        post --用户登录
        put --用户注册
        delete --用户信息修改
    '''

    @allow_cross
    def get(self):
        '''
            用户获取用户信息
            输出用户信息：
                u_name
                u_phone
                u_addr
                u_sex
                u_birthday
                is_vip
        :return:
        '''
        args = parsers()
        u_id = args.get('u_id')
        u_token = args.get('u_token')
        if u_id and u_token:
            is_legal = token.verify(u_token, u_id)
            if is_legal:   # 合法
                filter = {'u_id': u_id}
                u_data = mgOp.find_one(dbNameDict['userData'], filter)
                rd = {
                    'u_mail':u_data['u_mail'],
                    'u_name': u_data['u_name'],
                    'u_addr': u_data['u_addr'],
                    'u_sex': u_data['u_sex'],
                    'u_birthday': u_data['u_birthday'],
                    'is_vip': u_data['is_vip'],
                    'vip_start':u_data['vip_start'],
                    'vip_end': u_data['vip_end'],
                    'u_wechat':u_data['u_wechat'],
                    'u_facebook':u_data['u_facebook']
                }
                if(u_data['u_phone']):
                    rd['u_phone'] = hidSI.phone(u_data['u_phone'])
                return responseJson.correct(code='ok', data=rd)   # ok
            else:
                return responseJson.error_response(code='tokenFailure')   # 权限失效
        else:
            return responseJson.error_response(code='lackOfNecessaryParameters')   # 参数缺失

    @allow_cross
    def post(self):
        '''
            用户登录
        :return:
        '''
        args = parsers()
        u_id = args.get('u_id')  # 用户id
        u_token = args.get('u_token')  # 用户token
        u_mail = args.get('u_mail')   # 用户邮箱
        u_pwd = args.get('u_pwd')   # 用户密码

        u_wechat = args.get('u_wechat')   # 微信登录
        u_facebook = args.get('u_facebook')  # facebook 登录

        if u_id and u_token:  # u_id token 验证登录
            is_legal = token.verify(u_token, u_id)
            filter = {
                'u_id': u_id,
            }
            if is_legal:  # 合法
                if inquiry_vip(u_id):  # 更新用户vip数据
                    mgOp.update_one(dbName['userData'], filter, {'is_vip': '1'})
                new_token = token.create(u_id)
                rd = {
                    'uId': u_id,
                    'uToken': new_token
                }
                return responseJson.correct(code='ok', data=rd)
            else:     # 不合法
                return responseJson.error_response(code='tokenFailure')

        if u_mail and u_pwd:   # 邮箱密码登录
            may_u_id=ctId.uid(u_mail)
            filter = {
                'u_id': may_u_id,
            }
            u_data = mgOp.find_one(dbName['userData'], filter)
            if u_data:  # 有账号
                if u_data['u_status'] == '0':
                    return responseJson.error_response(code='accountIsNotActivated')
                if u_data.get('u_pwd') == md5Encode(u_pwd):  # 密码正确
                    if inquiry_vip(may_u_id):  # 更新用户vip数据
                        mgOp.find_one_and_update(dbName['userData'], filter, {'is_vip': '1'})
                    # 添加登录数据
                    mgOp.update_one(dbNameDict['userLoginData'], filter, {
                        'login_time': str(time.time()),     # 登陆时间
                        'u_ip': str(request.remote_addr)   # 登录ip
                    })
                    new_token = token.create(may_u_id)   # 创建token
                    rd = {
                        'uId': may_u_id,
                        'uToken': new_token,
                        'uName': u_data['u_name'],
                        'uSex': u_data['u_sex'],
                        'isVip': u_data['is_vip'],
                        'uStatus': u_data['u_status']
                    }
                    if u_data['u_phone']:
                        rd['uPhone'] = hidSI.phone(u_data['u_phone'])
                    return responseJson.correct(code='ok', data=rd)
                else:  #密码错误
                    return responseJson.error_response(code='accountOrPasswordError')
            else:  # 账号没有注册
                return responseJson.error_response(code='resourcesDoNotExist')

        # 提交的参数缺失
        return responseJson.error_response(code='lackOfNecessaryParameters')

    @allow_cross
    def put(self):
        '''
            注册新用户
        :return:
        '''
        args = parsers()
        u_name = args.get('u_name') # 用户假名   --必须
        u_mail = args.get('u_mail') # 用户邮箱   --必须
        u_pwd = args.get('u_pwd') # 用户密码 --必须
        #u_phone = args.get('u_phone') # 用户手机  --必须
        u_birthday = args.get('u_birthday') # 用户生日 必须
        u_sex = args.get('u_sex')  # 性别 F 女士  M 先生

        u_facebook = args.get('u_facebook')  # 绑定facebook 第三方注册
        u_wechat =  args.get('u_wechat')  # 绑定微信 第三方注册

        if u_name and u_mail and u_pwd and u_birthday:
            u_id = ctId.uid(u_mail)
            filter = {
                'u_id': u_id,
            }
            if mgOp.find_one(dbNameDict['userData'], filter):  # 对应uid存在
                return responseJson.error_response(code='mailboxHasBeenUsed')
            else:  # 不存在
                format_time = FormatIO().timestamp_format(time.time())  # 用户创建时间
                u_data = {
                    'u_id':u_id,
                    'u_name': u_name,
                    'u_mail': u_mail,
                    'u_pwd': md5Encode(u_pwd),
                    'u_birthday': u_birthday,
                    'u_facebook':'',  # 用户绑定facebook
                    'u_wechat':'',    # 用户绑定微信
                    'u_sex': u_sex,
                    'u_addr':{},        # 地址可有多项
                    'u_phone':'',
                    'format_time': format_time,
                    'create_time':str(time.time()),
                    'is_vip': '0',   # 是否vip
                    'u_status':'0',   # 0 表示未激活 1 表示正常 2 表示封号
                    'vip_start':'0000', # vip 开始时间 '0000'为初始化 该字符为时间戳
                    'vip_end':'0000', # vip结束时间
                    'mailing': '1',   # 订阅邮件 --会员自动订阅
                }
                mailing_data = {
                    'format_time': format_time,
                    'u_id': u_id,
                    'mail': u_mail
                }
                mgOp.insert_one(dbNameDict['mailingData'], mailing_data)  # 订阅官网邮件
                # 添加登录数据
                mgOp.insert_one(dbNameDict['userLoginData'], {
                    'u_id': u_id,
                    'login_time': str(time.time()),  # 登陆时间
                    'format_time':format_time,
                    'u_ip': str(request.remote_addr)  # 登录ip
                })
                mgOp.insert_one(dbNameDict['userData'], u_data)  # 添加数据库

                model_id = 'kpMail201803280101'   # 注册邮件模板id
                res = send_email_by_model(u_mail, u_name, model_id)  # 发送验证邮件
                # res = {'code':200, 'data':json.loads(r.text)['message'] }
                if res.get('code') == 200:
                    return responseJson.correct(code='ok', data=res.get('data'))
                else:
                    return responseJson.error_response(code='sendMailFailure') # 发送激活邮件失败
        else:
            return responseJson.error_response(code='lackOfNecessaryParameters')  # 参数缺失

    @allow_cross
    def delete(self):
        '''
            用户信息修改  -- 接口方法并不是那么合适，但是目前只有这么办了 ☺
            数据的格式验证由前端验证
        :return:
        '''
        args = parsers()
        u_id = args.get('u_id')
        u_token = args.get('u_token')
        if u_id and u_token:
            if token.verify(u_token, u_id):   # 凭据合法
                # 可更改项包括 用户假名 用户地址(是修改不是新增) 用户生日 用户性别 用户手机号码#
                u_name = args.get('u_name')
                u_addr = args.get('u_addr')
                u_birthday = args.get('u_birthday')
                u_sex = args.get('u_sex')
                u_phone = args.get('u_phone')
                up_data = {}
                if u_name:
                    up_data['u_name'] = u_name
                if u_addr:
                    up_data['u_addr'] = u_addr
                if u_birthday:
                    up_data['u_birthday'] = u_birthday
                if u_sex:
                    up_data['u_sex'] = u_sex
                if u_phone:
                    up_data['u_phone'] = u_phone
                filter = {
                    'u_id': u_id
                }
                if up_data:
                    bol = mgOp.update_one(dbNameDict['userData'], filter ,up_data)
                    if bol: # 修改成功
                        return responseJson.correct(code='ok', data={'msg':'修改信息成功'})
                    else:  # 失败
                        return responseJson.error_response(code='unknownError')
                else:
                    return responseJson.error_response(code='lackOfNecessaryParameters')
            else:  # 凭据非法
                return responseJson.error_response(code='tokenFailure')
        else:
            return responseJson.error_response(code='lackOfNecessaryParameters')  # 参数缺失

class Password(Resource):
    '''
        /u/pwd
        用户密码操作
        get -- 保留接口方法
        post -- 修改密码
        put -- 保留接口方法
        delete -- 保留接口方法
    '''
    @allow_cross
    def get(self):
        # 查询邮箱是否存在，存在发送验证码
        args = parsers()
        u_mail = args.get('u_mail')
        if u_mail:
            may_u_id = ctId.uid(u_mail)
            u_data = mgOp.find_one(dbNameDict['userData'],filter={'u_id':may_u_id})
            if u_data:
                # 存在发送验证码
                model_id = 'kpMail201803280101'  # 注册邮件模板id
                res = send_email_by_model(u_mail, u_data['u_name'], model_id)  # 发送验证邮件
                if res.get('code') == 200:
                    return responseJson.correct(code='ok', data=res.get('data'))
                else:
                    return responseJson.error_response(code='sendMailFailure') # 发送激活邮件失败
            else:
                return responseJson.error_response(code="resourcesDoNotExist")
        return responseJson.error_response(code='lackOfNecessaryParameters')

    @allow_cross
    def post(self):
        '''
            修改密码
        :return:
        '''
        args = parsers()
        u_id = args.get('u_id')
        u_token = args.get('u_token')
        u_pwd = args.get('u_pwd')
        u_npwd = args.get('u_npwd')  # 新密码
        u_mail = args.get('u_mail')
        m_code = args.get('code')
        if u_id and u_token and u_pwd and u_npwd:
            if token.verify(u_token, u_id):
                filter = {'u_id': u_id}
                if md5Encode(u_pwd) == mgOp.find_one(dbNameDict['userData'], filter)['u_pwd']:  # 密码对应
                    bol = mgOp.update_one(dbNameDict['userData'], filter, {'u_pwd': md5Encode(u_npwd)})  # 更新密码
                    if bol:
                        return responseJson.correct(code='ok', data={'msg': '修改密码成功'})   # 修改成功
                    else:
                        return responseJson.error_response(code='unknownError') # 失败
                else: # 旧密码不对应
                    return responseJson.error_response(code='originalPasswordError')
            else:
                return responseJson.error_response(code='tokenFailure')  # token失效

        if u_mail and u_pwd and m_code:
            act_time = mgOp.find_one(dbNameDict['msgCodeData'], {'u_mail':u_mail, 'm_code':m_code, 'status':'0'})['act_time']
            if act_time and act_time > time.time() - 7200:  # 激活时间有效
                may_u_id = ctId.uid(u_mail)
                user_data = mgOp.find_one(dbNameDict['userData'], {'u_id': may_u_id})
                if user_data:
                    mgOp.update_one(dbNameDict['userData'], {'u_id': may_u_id}, {'u_pwd': md5Encode(u_pwd)} )
                    return responseJson.correct(code='ok', data={'msg':'修改密码成功'})
                else:
                    return responseJson.error_response(code='resourcesDoNotExist')
            else:
                return responseJson.error_response(code='verificationCodeErrorOrVerificationTimeout')
        else:
            return responseJson.error_response(code='lackOfNecessaryParameters')

    @allow_cross
    def put(self):
        """
            修改密码 是否邮箱对应激活码
        :return:
        """
        args = parsers()
        u_mail = args.get('u_mail')
        m_code = args.get('code')
        code_data = mgOp.find_one(dbNameDict['msgCodeData'], {'u_mail':u_mail, 'm_code':m_code, 'status':'1'})
        if code_data:
            mgOp.update_one(dbNameDict['msgCodeData'],{'u_mail':u_mail, 'm_code':m_code,},{ 'status':'0', 'act_time':time.time()})
            return responseJson.correct(code="ok",data={'msg':'验证码正确'})
        else:
            return responseJson.error_response(code='verificationCodeErrorOrVerificationTimeout')

    @allow_cross
    def delete(self):
        return responseJson.error_response(code='RequestMethodError')



class Verificat(Resource):

    @allow_cross
    def get(self):
        args = parsers()
        code = args.get('code')
        u_mail = args.get('u_mail')
        way = args.get('way')
        if way == 'm':
            s_code = mgOp.find_one(dbNameDict['msgCodeData'], {'u_mail': u_mail})['m_code']
            if s_code == code:
                mgOp.update_one(dbNameDict['userData'],{'u_mail': u_mail}, {'u_status':'1'})
                user_data = mgOp.find_one(dbNameDict['userData'],{'u_mail': u_mail})
                rd = {
                    'uName': user_data['u_name'],
                    'uId': user_data['u_id'],
                    'uToken': token.create(user_data['u_id'])
                }
                return responseJson.correct(code='ok', data=rd)

class UserPsnAclt(Resource):
    @allow_cross
    def post(self):
        args = parsers()
        u_id = args.get('u_id')
        u_token = args.get('u_token')
        _code = args.get('code')

        if token.verify(u_token, u_id):
            code_data = mgOp.find_one(dbNameDict['productSerialNumber'], filter={'code': _code})
            if code_data:
                return responseJson.correct(code='ok', data=code_data)
            else:
                return  responseJson.error_response(code="resourcesDoNotExist")
        else:
            return responseJson.error_response(code="tokenFailure")





